// 类似react的hook函数

import { OrderType } from '@/enums'
import {
  reqCancelOrder,
  reqDeleteOrder,
  reqFollowDoctor,
  reqGetPrescriptionPic
} from '@/services/consult'
import { reqGetMedicalOrderDetail } from '@/services/order'
import { sendMobileCode } from '@/services/user'
import type { ConsultOrderItem, FollowType } from '@/types/consult'
import type { OrderDetail } from '@/types/oreder'
import type { CodeType } from '@/types/user'
import { ImagePreview, Toast, type FormInstance } from 'vant'
import { onMounted, onUnmounted, ref } from 'vue'

// 封装逻辑，规范 useXxx，表示使用某功能
export const useFollsw = (type: FollowType = 'doc') => {
  // 定义加载状态
  const loading = ref(false)
  // 关注取消关注的方法
  // {a, b} 类型，传值得时候 {a, b, c} 也可以，这是类型兼容：多的可以给少的
  const follow = async (item: { id: string; likeFlag: 0 | 1 }) => {
    // console.log(item)
    // 进来先改为true 让它先转起来
    loading.value = true
    try {
      await reqFollowDoctor(type, item.id)
      // 判断是够关注，如果关注了就是1  没关注就是0
      item.likeFlag = item.likeFlag === 0 ? 1 : 0
    } finally {
      // 因为成功和失败最后都要把加载关掉
      // 所以我们可以写在finally,不管成功和失败执行
      loading.value = false
    }
  }
  return {
    follow,
    loading
  }
}

// 第二个hook，点击查看原始处方，
export const useShowprescription = () => {
  const showPrescription = async (id?: string) => {
    if (id) {
      const res = await reqGetPrescriptionPic(id)
      ImagePreview([res.data.url])
    }
  }
  return { showPrescription }
}

// 第三个hook 取消问诊
export const useHandleCancel = () => {
  // 给按钮加loading状态
  const loading = ref(false)
  const handleCancel = async (item: ConsultOrderItem) => {
    // 状态改为加载中
    loading.value = true
    try {
      // 发请求
      await reqCancelOrder(item.id)
      // 发送取消后，修改item的状态
      item.status = OrderType.ConsultCancel
      // 且需要修改页面显示的文字
      item.statusValue = '已取消'
      // 给提示取消问诊成功
      Toast.success('取消成功')
    } catch (error) {
      // 失败也给提示
      Toast.fail('取消失败')
    } finally {
      // 不管成功或者失败都会执行finally中代码，因此可以在这里吧按钮状态改为false
      loading.value = false
    }
  }

  return {
    loading,
    handleCancel
  }
}

// 第四个 删除订单 hook
export const useHandleOrder = (callback: () => void) => {
  // 给删除按钮加loading状态  删除
  const deleteLoading = ref(false)
  const handleOrder = async (item: ConsultOrderItem) => {
    // 执行后就改为true
    deleteLoading.value = true
    try {
      // 发请求删除服务器数据
      await reqDeleteOrder(item.id)
      // 在子传父 传过去id在父组件中删除list中的这条数据
      // 抽离hook 在不同的地方进行删除，后面处理的逻辑不一样，所以emit事件 当做回调函数穿进去，里面定义一个函数执行就好
      // emit('onDelete', item.id)
      callback && callback() // 传进来的回调函数 执行完删除后需要做什么事情
      Toast.success('删除成功')
    } catch (error) {
      Toast.fail('删除失败')
    } finally {
      deleteLoading.value = false
    }
  }
  return {
    deleteLoading,
    handleOrder
  }
}

/**
 * 订单详情hook
 * @param id
 */
export const useOrder = (id: string) => {
  const order = ref<OrderDetail>()
  const loading = ref(false)
  onMounted(async () => {
    try {
      loading.value = true
      const res = await reqGetMedicalOrderDetail(id)
      order.value = res.data
    } finally {
      loading.value = false
    }
  })
  return {
    order,
    loading
  }
}

/**
 * 登录hook
 */

export const useSendCode = (mobile: string, type: CodeType) => {
  // 开启一个时间
  const timer = ref(0)
  // 定义一个倒计时
  let timeId: ReturnType<typeof setInterval>
  // 发送请求登录验证码
  // 拿DOM
  const formRef = ref<FormInstance>()
  const send = async () => {
    // 如果timer的时间不为零 就return不执行
    if (timer.value > 0) return
    // 验证码登录时  校验手机号
    await formRef.value?.validate('mobile')
    // 发请求拿验证码
    const res = await sendMobileCode(mobile, type)
    console.log(res.data)
    // 给提示
    Toast.success('发送成功')
    // 给定时器时间 赋值 为60s
    timer.value = 60
    // 执行定时器前先清除定时器
    clearInterval(timeId)
    // 启用定时器
    timeId = setInterval(() => {
      // 每隔一秒时间 减一
      timer.value--
      // 判断 如果时间小于等于零时 return并清楚定时器
      if (timer.value <= 0) {
        return clearInterval(timeId)
      }
    }, 1000)
  }

  // 移除组件时清除定时器
  onUnmounted(() => {
    clearInterval(timeId)
  })
  return {
    timer,
    send,
    formRef
  }
}
